<template>
  <div class="planet-system-container" ref="containerRef">
    <div class="system-controls">
      <div class="control-group">
        <label for="speedControl">时间速度:</label>
        <input 
          id="speedControl" 
          type="range" 
          v-model.number="timeSpeed" 
          min="0.1" 
          max="10" 
          step="0.1"
        />
        <span>{{ timeSpeed.toFixed(1) }}x</span>
      </div>
      <div class="control-group">
        <label>
          <input type="checkbox" v-model="showOrbits" /> 显示轨道
        </label>
      </div>
      <div class="control-group">
        <label>
          <input type="checkbox" v-model="showLabels" /> 显示标签
        </label>
      </div>
      <div class="control-group">
        <label>
          <input type="checkbox" v-model="realScale" /> 真实比例
        </label>
      </div>
      <div class="control-group">
        <select v-model="targetPlanet" @change="focusPlanet">
          <option value="sun">太阳</option>
          <option value="mercury">水星</option>
          <option value="venus">金星</option>
          <option value="earth">地球</option>
          <option value="mars">火星</option>
          <option value="jupiter">木星</option>
          <option value="saturn">土星</option>
          <option value="uranus">天王星</option>
          <option value="neptune">海王星</option>
        </select>
      </div>
    </div>
  </div>
</template>

<script>
import { ref, computed, onMounted, onUnmounted, watch } from 'vue'
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
import { Text } from 'troika-three-text'
import { 
  initOrbitalCalculationWorker, 
  calculateAllOrbitalPositions, 
  calculateAllOrbits, 
  optimizedOrbitalCalculation, 
  cleanupWorkers 
} from '../services/WorkerManager.js'

export default {
  name: 'PlanetSystem',
  setup() {
    const containerRef = ref(null)
    let scene = null
    let camera = null
    let renderer = null
    let controls = null
    let animationId = null
    let clock = null
    
    // 状态变量
    const timeSpeed = ref(1.0)
    const showOrbits = ref(true)
    const showLabels = ref(true)
    const realScale = ref(false)
    const targetPlanet = ref('sun')
    
    // Worker状态
    let orbitalWorker = null
    let lastCalculationTime = 0
    let calculationInterval = 100 // 计算间隔（毫秒）
    
    // 存储场景对象的引用
    const objects = {
      sun: null,
      planets: {},
      orbits: {},
      labels: {}
    }
    
    // 行星数据（基于真实参数）
    const planetData = {
      mercury: { 
        name: '水星', 
        distance: 39, 
        radius: 2440, 
        color: 0xaaaaaa, 
        orbitSpeed: 47.4, 
        rotationSpeed: 1407.6, 
        yearLength: 87.97,
        dayLength: 1407.6
      },
      venus: { 
        name: '金星', 
        distance: 72, 
        radius: 6052, 
        color: 0xe3a95c, 
        orbitSpeed: 35.0, 
        rotationSpeed: 2802.0, 
        yearLength: 224.7,
        dayLength: 2802.0
      },
      earth: { 
        name: '地球', 
        distance: 100, 
        radius: 6371, 
        color: 0x2233ff, 
        orbitSpeed: 29.8, 
        rotationSpeed: 23.93, 
        yearLength: 365.26,
        dayLength: 23.93,
        moons: [
          { name: '月球', distance: 30, radius: 1737, color: 0xaaaaaa, orbitSpeed: 1.022, rotationSpeed: 27.32 }
        ]
      },
      mars: { 
        name: '火星', 
        distance: 152, 
        radius: 3390, 
        color: 0xff3300, 
        orbitSpeed: 24.1, 
        rotationSpeed: 24.6, 
        yearLength: 686.98,
        dayLength: 24.6,
        moons: [
          { name: '火卫一', distance: 15, radius: 11, color: 0x888888, orbitSpeed: 0.31 },
          { name: '火卫二', distance: 25, radius: 6, color: 0x666666, orbitSpeed: 0.12 }
        ]
      },
      jupiter: { 
        name: '木星', 
        distance: 520, 
        radius: 69911, 
        color: 0xffaa88, 
        orbitSpeed: 13.1, 
        rotationSpeed: 9.9, 
        yearLength: 4332.59,
        dayLength: 9.9,
        hasRings: true,
        moons: [
          { name: '木卫一', distance: 42, radius: 1821, color: 0xff8888, orbitSpeed: 42.8 },
          { name: '木卫二', distance: 67, radius: 1569, color: 0x88aaff, orbitSpeed: 35.5 },
          { name: '木卫三', distance: 107, radius: 2634, color: 0xaaaaaa, orbitSpeed: 26.5 },
          { name: '木卫四', distance: 188, radius: 2410, color: 0x999999, orbitSpeed: 18.1 }
        ]
      },
      saturn: { 
        name: '土星', 
        distance: 958, 
        radius: 58232, 
        color: 0xffcc66, 
        orbitSpeed: 9.7, 
        rotationSpeed: 10.7, 
        yearLength: 10759.2,
        dayLength: 10.7,
        hasRings: true,
        ringColor: 0xffddaa,
        moons: [
          { name: '土卫六', distance: 122, radius: 2575, color: 0x886644, orbitSpeed: 9.6 }
        ]
      },
      uranus: { 
        name: '天王星', 
        distance: 1920, 
        radius: 25362, 
        color: 0x99ccff, 
        orbitSpeed: 6.8, 
        rotationSpeed: 17.2, 
        yearLength: 30688.5,
        dayLength: 17.2,
        hasRings: true,
        ringColor: 0x777799,
        moons: [
          { name: '天卫三', distance: 58, radius: 788, color: 0x9999aa, orbitSpeed: 6.8 }
        ]
      },
      neptune: { 
        name: '海王星', 
        distance: 3005, 
        radius: 24622, 
        color: 0x3366ff, 
        orbitSpeed: 5.4, 
        rotationSpeed: 16.1, 
        yearLength: 60195,
        dayLength: 16.1,
        hasRings: true,
        ringColor: 0x223366,
        moons: [
          { name: '海卫一', distance: 35, radius: 1353, color: 0x555577, orbitSpeed: 4.4 }
        ]
      }
    }
    
    // 初始化场景
    const initScene = () => {
      if (!containerRef.value) return
      
      // 创建场景
      scene = new THREE.Scene()
      scene.background = new THREE.Color(0x000011)
      
      // 创建相机
      camera = new THREE.PerspectiveCamera(
        75, 
        containerRef.value.clientWidth / containerRef.value.clientHeight,
        0.1, 
        100000
      )
      camera.position.set(500, 300, 500)
      
      // 创建渲染器
      renderer = new THREE.WebGLRenderer({ antialias: true })
      renderer.setSize(containerRef.value.clientWidth, containerRef.value.clientHeight)
      renderer.setPixelRatio(window.devicePixelRatio)
      containerRef.value.appendChild(renderer.domElement)
      
      // 添加轨道控制器
      controls = new OrbitControls(camera, renderer.domElement)
      controls.enableDamping = true
      controls.dampingFactor = 0.05
      controls.autoRotate = false
      
      // 添加环境光
      const ambientLight = new THREE.AmbientLight(0x050505)
      scene.add(ambientLight)
      
      // 创建时钟
      clock = new THREE.Clock()
      
      // 创建太阳系
      createSun()
      createPlanets()
      
      // 开始动画
      animate()
      
      // 监听窗口大小变化
      window.addEventListener('resize', handleResize)
    }
    
    // 创建太阳
    const createSun = () => {
      // 太阳半径（非真实比例，为了可视化）
      const radius = realScale.value ? 696340 / 1000 : 20
      
      // 创建太阳材质
      const sunMaterial = new THREE.MeshBasicMaterial({ 
        color: 0xffff00,
        emissive: 0xffff00
      })
      
      // 创建太阳几何体
      const sunGeometry = new THREE.SphereGeometry(radius, 32, 32)
      
      // 创建太阳网格
      const sun = new THREE.Mesh(sunGeometry, sunMaterial)
      scene.add(sun)
      
      // 创建太阳发光效果
      const sunLight = new THREE.PointLight(0xffff00, 2, 10000)
      sun.add(sunLight)
      
      // 存储太阳引用
      objects.sun = sun
      
      // 创建太阳标签
      createPlanetLabel('太阳', sun, 0xffcc00)
    }
    
    // 创建行星
    const createPlanets = () => {
      Object.entries(planetData).forEach(([key, data]) => {
        // 创建行星轨道
        if (showOrbits.value) {
          createOrbit(data.distance)
        }
        
        // 创建行星父对象（用于轨道运动）
        const orbitGroup = new THREE.Object3D()
        scene.add(orbitGroup)
        
        // 创建行星父对象（用于自转轴倾斜）
        const planetGroup = new THREE.Object3D()
        
        // 模拟行星自转轴倾斜
        if (key === 'earth') planetGroup.rotation.x = 0.4091
        if (key === 'saturn') planetGroup.rotation.x = 0.466
        if (key === 'uranus') planetGroup.rotation.x = 1.77
        
        orbitGroup.add(planetGroup)
        
        // 计算行星半径
        const radius = realScale.value ? data.radius / 5000 : Math.max(1, data.radius / 2000)
        
        // 创建行星几何体
        const planetGeometry = new THREE.SphereGeometry(radius, 32, 32)
        
        // 创建行星材质
        const planetMaterial = new THREE.MeshPhongMaterial({ 
          color: data.color,
          shininess: 10
        })
        
        // 创建行星网格
        const planet = new THREE.Mesh(planetGeometry, planetMaterial)
        planet.position.set(data.distance, 0, 0)
        planetGroup.add(planet)
        
        // 添加光环（土星、木星、天王星、海王星）
        if (data.hasRings) {
          const ringRadius = radius * 1.5
          const ringGeometry = new THREE.RingGeometry(ringRadius, ringRadius * 1.8, 32)
          const ringMaterial = new THREE.MeshBasicMaterial({ 
            color: data.ringColor || 0xaaaaaa, 
            side: THREE.DoubleSide,
            transparent: true,
            opacity: 0.6
          })
          
          const ring = new THREE.Mesh(ringGeometry, ringMaterial)
          ring.rotation.x = Math.PI / 2
          planetGroup.add(ring)
          ring.position.set(data.distance, 0, 0)
        }
        
        // 创建卫星
        if (data.moons) {
          data.moons.forEach(moon => {
            createMoon(planet, moon, radius)
          })
        }
        
        // 存储行星引用
        objects.planets[key] = {
          mesh: planet,
          orbitGroup: orbitGroup,
          planetGroup: planetGroup,
          data: data,
          orbitAngle: Math.random() * Math.PI * 2 // 随机初始轨道角度
        }
        
        // 创建行星标签
        createPlanetLabel(data.name, planet, data.color)
      })
    }
    
    // 创建卫星
    const createMoon = (planet, moonData, planetRadius) => {
      // 创建卫星轨道
      const moonOrbitGroup = new THREE.Object3D()
      planet.add(moonOrbitGroup)
      
      // 卫星轨道距离（基于行星大小）
      const orbitDistance = planetRadius * 1.5 + moonData.distance / 20
      
      // 卫星大小
      const moonRadius = Math.max(0.1, moonData.radius / 2000)
      
      // 创建卫星几何体和材质
      const moonGeometry = new THREE.SphereGeometry(moonRadius, 16, 16)
      const moonMaterial = new THREE.MeshPhongMaterial({ 
        color: moonData.color,
        shininess: 5
      })
      
      // 创建卫星网格
      const moon = new THREE.Mesh(moonGeometry, moonMaterial)
      moon.position.set(orbitDistance, 0, 0)
      moonOrbitGroup.add(moon)
      
      // 存储卫星数据
      moon.orbitGroup = moonOrbitGroup
      moon.orbitAngle = Math.random() * Math.PI * 2
      moon.orbitSpeed = moonData.orbitSpeed
      
      return moon
    }
    
    // 创建行星轨道（使用Web Worker）
    const createOrbit = async (radius, planetName = null) => {
      try {
        // 轨道材质
        const orbitMaterial = new THREE.LineBasicMaterial({
          color: 0x444444,
          transparent: true,
          opacity: 0.5,
          linewidth: 1
        })
        
        // 使用Web Worker计算轨道
        if (planetName && calculateAllOrbits) {
          const orbitData = await calculateAllOrbits({[planetName]: {distance: radius}}, 120)
          const orbitPoints = orbitData[planetName]
          
          if (orbitPoints && orbitPoints.length > 0) {
            const points = orbitPoints.map(point => 
              new THREE.Vector3(point.x, point.y, point.z)
            )
            
            const orbitGeometry = new THREE.BufferGeometry().setFromPoints(points)
            const orbit = new THREE.Line(orbitGeometry, orbitMaterial)
            
            scene.add(orbit)
            return orbit
          }
        }
        
        // 降级方案：在主线程中创建轨道
        return createOrbitFallback(radius)
      } catch (error) {
        console.error('创建轨道失败:', error)
        // 降级方案：在主线程中创建轨道
        return createOrbitFallback(radius)
      }
    }
    
    // 降级方案：在主线程中创建轨道
    const createOrbitFallback = (radius) => {
      const orbitGeometry = new THREE.RingGeometry(radius, radius + 0.1, 60) // 减少点数量提高性能
      const orbitMaterial = new THREE.MeshBasicMaterial({ 
        color: 0x333333,
        side: THREE.DoubleSide,
        transparent: true,
        opacity: 0.5
      })
      
      const orbit = new THREE.Mesh(orbitGeometry, orbitMaterial)
      orbit.rotation.x = Math.PI / 2
      scene.add(orbit)
      
      return orbit
    }
    
    // 创建行星标签
    const createPlanetLabel = (name, planet, color) => {
      const text = new Text()
      text.text = name
      text.fontSize = 2
      text.color = color
      text.anchorX = 'center'
      text.anchorY = 'bottom'
      text.textAlign = 'center'
      text.outlineWidth = 0.1
      text.outlineColor = 0x000000
      text.sync()
      
      // 将标签添加到行星附近，但稍高一点
      const labelGroup = new THREE.Object3D()
      labelGroup.position.set(0, planet.geometry.parameters.radius + 3, 0)
      labelGroup.add(text)
      
      planet.add(labelGroup)
      
      // 初始隐藏标签
      labelGroup.visible = showLabels.value
      
      // 存储标签引用
      objects.labels[name] = labelGroup
    }
    
    // 聚焦到特定行星
    const focusPlanet = () => {
      if (!controls || !objects.planets[targetPlanet.value] && targetPlanet.value !== 'sun') return
      
      if (targetPlanet.value === 'sun') {
        controls.target.set(0, 0, 0)
        camera.position.set(500, 300, 500)
      } else {
        const planet = objects.planets[targetPlanet.value]
        const distance = planet.data.distance * 2
        controls.target.copy(planet.mesh.position)
        camera.position.set(distance, distance / 2, distance)
      }
      
      controls.update()
    }
    
    // 动画循环
    const animate = async () => {
      try {
        animationId = requestAnimationFrame(animate)
        const now = Date.now()
        const delta = clock.getDelta() * timeSpeed.value
        
        // 更新太阳旋转
        if (objects.sun) {
          objects.sun.rotation.y += 0.001 * delta
        }
        
        // 限制计算频率，避免过度计算
        if (now - lastCalculationTime > calculationInterval) {
          lastCalculationTime = now
          
          try {
            // 准备数据
            const currentPositions = {}
            Object.entries(objects.planets).forEach(([planetName, planet]) => {
              currentPositions[planetName] = {
                orbitAngle: planet.orbitAngle,
                distance: planet.data.distance,
                orbitSpeed: (2 * Math.PI) / (planet.data.yearLength / 365.26),
                rotationSpeed: (2 * Math.PI) / (24 / planet.data.dayLength),
                moons: planet.mesh.children.filter(child => child.orbitGroup).map(child => ({
                  name: child.name,
                  orbitAngle: child.orbitAngle,
                  orbitSpeed: (2 * Math.PI) * (child.orbitSpeed / 24),
                  distance: child.position.length()
                }))
              }
            })
            
            // 使用Web Worker计算所有行星位置
            const newPositions = await optimizedOrbitalCalculation(currentPositions, delta)
            
            // 更新场景中的行星位置
            Object.entries(newPositions).forEach(([planetName, positionData]) => {
              const planet = objects.planets[planetName]
              if (planet) {
                // 更新行星轨道位置
                planet.orbitAngle = positionData.orbitAngle
                planet.orbitGroup.rotation.y = planet.orbitAngle
                
                // 更新行星自转
                planet.planetGroup.rotation.y += positionData.rotationDelta
                
                // 更新卫星位置
                if (positionData.moons) {
                  positionData.moons.forEach((moonData, index) => {
                    const moon = planet.mesh.children.find(child => child.orbitGroup)[index]
                    if (moon) {
                      moon.orbitAngle = moonData.orbitAngle
                      moon.orbitGroup.rotation.y = moon.orbitAngle
                    }
                  })
                }
              }
            })
          } catch (error) {
            console.warn('Web Worker计算失败，使用主线程降级方案:', error)
            // 降级方案：在主线程中计算
            updatePlanetsInMainThread(delta)
          }
        } else {
          // 当跳过计算时，仍然更新基本旋转
          Object.values(objects.planets).forEach(planet => {
            // 自转
            const rotationSpeed = (2 * Math.PI) / (24 / planet.data.dayLength) * delta
            planet.planetGroup.rotation.y += rotationSpeed
          })
        }
        
        // 更新控制器
        if (controls) {
          controls.update()
        }
        
        // 渲染场景
        renderer.render(scene, camera)
      } catch (error) {
        console.error('动画循环错误:', error)
      }
    }
    
    // 降级方案：在主线程中更新行星位置
    const updatePlanetsInMainThread = (delta) => {
      // 更新行星运动
      Object.values(objects.planets).forEach(planet => {
        // 轨道运动（公转）
        const orbitSpeed = (2 * Math.PI) / (planet.data.yearLength / 365.26) * delta
        planet.orbitAngle += orbitSpeed
        planet.orbitGroup.rotation.y = planet.orbitAngle
        
        // 自转
        const rotationSpeed = (2 * Math.PI) / (24 / planet.data.dayLength) * delta
        planet.planetGroup.rotation.y += rotationSpeed
        
        // 更新卫星运动
        planet.mesh.children.forEach(child => {
          if (child.orbitGroup) {
            // 卫星轨道运动
            child.orbitAngle += (2 * Math.PI) * (child.orbitSpeed / 24) * delta
            child.orbitGroup.rotation.y = child.orbitAngle
          }
        })
      })
    }
    
    // 处理窗口大小变化
    const handleResize = () => {
      if (!containerRef.value || !camera || !renderer) return
      
      const { clientWidth, clientHeight } = containerRef.value
      
      camera.aspect = clientWidth / clientHeight
      camera.updateProjectionMatrix()
      
      renderer.setSize(clientWidth, clientHeight)
    }
    
    // 监听轨道显示状态
    watch(showOrbits, (show) => {
      // 更新轨道显示
      Object.values(objects.orbits).forEach(orbit => {
        orbit.visible = show
      })
    })
    
    // 监听标签显示状态
    watch(showLabels, (show) => {
      Object.values(objects.labels).forEach(label => {
        label.visible = show
      })
    })
    
    // 监听比例变化
    watch(realScale, () => {
      // 重新创建太阳系以应用新的比例
      if (scene) {
        // 清理现有对象
        while (scene.children.length > 0) {
          const object = scene.children[0]
          scene.remove(object)
          
          // 释放几何体和材质
          if (object.geometry) object.geometry.dispose()
          if (object.material) {
            if (Array.isArray(object.material)) {
              object.material.forEach(m => m.dispose())
            } else {
              object.material.dispose()
            }
          }
        }
        
        // 重置对象引用
        objects.sun = null
        objects.planets = {}
        objects.orbits = {}
        objects.labels = {}
        
        // 重新创建太阳系
        createSun()
        createPlanets()
      }
    })
    
    // 组件挂载时初始化
    onMounted(async () => {
      try {
        // 初始化Web Worker
        orbitalWorker = await initOrbitalCalculationWorker()
        console.log('轨道计算Worker初始化成功')
      } catch (error) {
        console.warn('Web Worker初始化失败，将使用主线程计算:', error)
      }
      
      // 初始化场景
      initScene()
    })
    
    // 组件卸载时清理
      onUnmounted(() => {
        if (animationId) {
          cancelAnimationFrame(animationId)
        }
        
        if (controls) {
          controls.dispose()
        }
        
        // 清理Web Worker
        cleanupWorkers()
        orbitalWorker = null
        
        // 清理Three.js资源
        if (renderer) {
          renderer.dispose()
          if (containerRef.value && renderer.domElement) {
            containerRef.value.removeChild(renderer.domElement)
          }
        }
        
        // 释放几何体和材质资源
        if (scene) {
          scene.traverse(obj => {
            if (obj.geometry) obj.geometry.dispose()
            if (obj.material) {
              if (Array.isArray(obj.material)) {
                obj.material.forEach(m => m.dispose())
              } else {
                obj.material.dispose()
              }
            }
          })
        }
        
        // 释放对象引用
        for (const key in objects) {
          if (objects[key] && typeof objects[key].dispose === 'function') {
            objects[key].dispose()
          }
          objects[key] = null
        }
        
        window.removeEventListener('resize', handleResize)
      })
    
    return {
      containerRef,
      timeSpeed,
      showOrbits,
      showLabels,
      realScale,
      targetPlanet,
      focusPlanet
    }
  }
}
</script>

<style scoped>
.planet-system-container {
  width: 100%;
  height: 100%;
  position: absolute;
  top: 0;
  left: 0;
  overflow: hidden;
}

.system-controls {
  position: absolute;
  top: 20px;
  right: 20px;
  background-color: rgba(0, 0, 0, 0.7);
  padding: 15px;
  border-radius: 8px;
  backdrop-filter: blur(10px);
  z-index: 10;
  color: #fff;
  font-family: Arial, sans-serif;
  font-size: 14px;
  border: 1px solid rgba(255, 255, 255, 0.1);
  min-width: 200px;
}

.control-group {
  margin-bottom: 12px;
  display: flex;
  align-items: center;
  gap: 10px;
}

.control-group:last-child {
  margin-bottom: 0;
}

.control-group label {
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 5px;
  white-space: nowrap;
}

.control-group input[type="range"] {
  width: 100px;
  cursor: pointer;
}

.control-group input[type="checkbox"] {
  cursor: pointer;
  width: 16px;
  height: 16px;
}

.control-group select {
  width: 100%;
  padding: 5px;
  background-color: rgba(255, 255, 255, 0.1);
  color: white;
  border: 1px solid rgba(255, 255, 255, 0.2);
  border-radius: 4px;
  cursor: pointer;
}

.control-group select option {
  background-color: #222;
  color: white;
}

.control-group span {
  min-width: 35px;
  text-align: center;
  color: #aaa;
  font-size: 12px;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .system-controls {
    top: 10px;
    right: 10px;
    left: 10px;
    padding: 10px;
    font-size: 12px;
  }
  
  .control-group {
    margin-bottom: 8px;
  }
  
  .control-group input[type="range"] {
    width: 80px;
  }
}
</style>